import { dateUtil } from '/@/utils/dateUtil';

import { FormSchemaInner, Rule } from '/@/components/Form';
import { isEmpty, isNil, isString, split } from 'lodash-es';

const pattern = {
  empty: /^\s*$/g, //空
  mobile:
    /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[189]))\d{8}$/, //最新的手机号正则
  tel: /^1\d{10}$/, //手机号
  phone: /^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/, //座机号
  tax: /^[A-Z0-9]{15}$|^[A-Z0-9]{17}$|^[A-Z0-9]{18}$|^[A-Z0-9]{20}$/, //税号
  number: /^\d+$/, //数字组合
  integer: /^[1-9]+\d*$/, //正整数不含0
  positiveinteger: /^(0|[1-9][0-9]*)$/, //正整数包含0
  plus: /^\d+(\.\d{1,4})?$/, //正数4位小数
  invoice: /^\d+(\.\d{1,2})?$/, //正数2位小数
  email: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/, //邮箱
  time: /^\d{1,4}(-)(1[0-2]|0?[1-9])\1(0?[1-9]|[1-2]\d|30|31)$/, //时间正则
  numerical: /^(\-)?\d+(\.\d{1,4})?$/, //正负数值4位小数
  numerical2: /^(\-)?\d+(\.\d{1,2})?$/, //正负数值2位小数
  scale: /^(1|0(\.\d{1,2})?)$/, //0-1区间|两位小数,
  percentage: /^(\d{1,2}(\.\d{1,2})?|100)$/, //0-100区间|两位小数,
  serial: /^[0-9a-zA-Z\-\_\|]*$/, //序列号正则
  variable: /^[a-zA-Z][a-zA-Z0-9_]*$/, //变量命名规则
  numeral: /^[0-9]/, //数字开头,
  capital: /[A-Z]/, //大写字母
  money: /^(\d+(\.\d{1,2})?)$/, //人民币
  idcard:
    /^\d{6}((((((19|20)\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|(((19|20)\d{2})(0[13578]|1[02])31)|((19|20)\d{2})02(0[1-9]|1\d|2[0-8])|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))0229))\d{3})|((((\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|((\d{2})(0[13578]|1[02])31)|((\d{2})02(0[1-9]|1\d|2[0-8]))|(([13579][26]|[2468][048]|0[048])0229))\d{2}))(\d|X|x)$/,
};
export const rules = {
  startTime(endTime, required) {
    return [
      {
        required: required ? required : false,
        validator: (_, value) => {
          if (required && !value) {
            return Promise.reject('请选择开始时间');
          }
          if (endTime && value && dateUtil(endTime).isBefore(value)) {
            return Promise.reject('开始时间需小于结束时间');
          }
          return Promise.resolve();
        },
        trigger: 'change',
      },
    ];
  },
  endTime(startTime, required) {
    return [
      {
        required: required ? required : false,
        validator: (_, value) => {
          if (required && !value) {
            return Promise.reject('请选择结束时间');
          }
          if (startTime && value && dateUtil(value).isBefore(startTime)) {
            return Promise.reject('结束时间需大于开始时间');
          }
          return Promise.resolve();
        },
        trigger: 'change',
      },
    ];
  },
  confirmPassword(values, required, passwordField = 'password') {
    return [
      {
        required: required ? required : false,
        validator: (_, value) => {
          if (!value) {
            return Promise.reject('密码不能为空');
          }
          if (value !== values[passwordField]) {
            return Promise.reject('两次输入的密码不一致!');
          }
          return Promise.resolve();
        },
      },
    ];
  },

  uniqueFieldValidation(
    fn: Fn,
    field: string | object,
    schema: FormSchemaInner,
    model: Recordable,
    required?: boolean,
    message?: string,
  ) {
    const vali: Rule = {
      validator: (rule, value) => {
        if (!(value && value.trim())) {
          return Promise.resolve();
        }
        let params: any = {};
        if (isString(field)) {
          const strArr = split(field, ',');
          for (const key in strArr) {
            if (model && model[strArr[key]]) {
              params[strArr[key]] = model[strArr[key]];
            }
          }
        } else {
          params = field;
        }
        params[rule['field']] = value;
        if (!value && (required ?? true)) {
          return Promise.reject(`请输入${schema.label}`);
        }
        return new Promise<void>((resolve, reject) => {
          fn(params)
            .then((res) => {
              res ? resolve() : reject(message ? message : `${value} 已存在`);
            })
            .catch((err) => {
              reject(err || '验证失败');
            });
        });
      },
      trigger: 'blur',
    };
    const rules: Rule[] = [];
    if (required ?? true) {
      rules.push({
        required: true,
        message: `请输入${schema.label}`,
        trigger: ['change', 'blur'],
      });
    }
    rules.push(vali);
    return rules;
  },
  validateNotEmpty: (key: keyof typeof pattern, msg = '时间'): Rule => {
    return {
      validator: (_, value) => {
        if (isNil(pattern[key])) {
          return Promise.reject('正则key不存在');
        }

        if (!isEmpty(value)) {
          if (!pattern[key].test(value)) {
            return Promise.reject(`${msg}`);
          } else {
            return Promise.resolve();
          }
        } else {
          return Promise.resolve();
        }
      },
    };
  },
};
//正则处理
export const validatePattern = (key: keyof typeof pattern): RegExp => {
  return pattern[key as string];
};
interface IDefaultValidateOptions {
  maxlen?: number;
  isrequired?: boolean;
  preg?: keyof typeof pattern;
  msg?: string;
  requiredMsg?: string;
  otherRule?: Rule;
}
export const defaultRule = (validateOpt?: IDefaultValidateOptions): Rule[] => {
  const defaultRule: Rule[] = [];
  defaultRule.push({
    required: validateOpt?.isrequired ?? true,
    message: validateOpt?.requiredMsg,
  });
  defaultRule.push({
    max: validateOpt?.maxlen ?? 30,
    min: 0,
  });
  if (!isNil(validateOpt?.preg)) {
    const vali: Rule = {
      validator: async (_, value) => {
        if (!isEmpty(value)) {
          const preg = validateOpt!.preg as string;
          if (!pattern[preg].test(value)) {
            return Promise.reject(validateOpt?.msg ?? '验证失败');
          }
        }
        return Promise.resolve();
      },
      trigger: 'blur',
    };
    defaultRule.push(vali);
  }
  if (!isNil(validateOpt?.otherRule)) {
    defaultRule.push(validateOpt!.otherRule);
  }
  return defaultRule;
};
